using System;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
using System.Web;
using System.Collections;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.ComponentModel;
using System.Collections.Generic;

namespace Stratman.Web.VSTS.Services
{
    /// <summary>
    /// Web services that listens for changes to work items:  if it detects that the completed hours for a work
    /// item have changed, it will add a corresponding entry to the user's timesheet for that day.
    /// </summary>
    [WebService(Namespace = "http://schemas.conchango.com/TeamFoundation/2005/06/Services/Notification/Extensibility", Description = "")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    public class UpdateTimesheet : EndpointBase
    {
        /// <summary>
        /// Endpoint required to accept incoming <see cref="WorkItemChangedEvent"/> notifications.
        /// </summary>
        /// <param name="eventXml">Serialized version of the <see cref="WorkItemChangedEvent"/></param>
        /// <param name="tfsIdentityXml">Serialized version of <see cref="TFSIdentity"/></param>
        [WebMethod]
        [SoapDocumentMethod("http://schemas.microsoft.com/TeamFoundation/2005/06/Services/Notification/03/Notify", RequestNamespace = "http://schemas.microsoft.com/TeamFoundation/2005/06/Services/Notification/03")]
        public void Notify(string eventXml, string tfsIdentityXml)
        {
            WorkItemChangedEvent workItemChangedEvent = this.CreateInstance<WorkItemChangedEvent>(eventXml);
            TFSIdentity tfsIdentity = this.CreateInstance<TFSIdentity>(tfsIdentityXml);
            double workAmountChange = 0;
            int workItemId = 0;
            int revision = 0;
            TimesheetSettings timesheetSettings = (TimesheetSettings)ConfigurationManager.GetSection("timesheetSettings");

            // Get the work item ID and the revision number
            foreach (IntegerField field in workItemChangedEvent.CoreFields.IntegerFields)
            {
                if (field.ReferenceName == "System.Id")
                    workItemId = Convert.ToInt32(field.NewValue);

                else if (field.ReferenceName == "System.Rev")
                    revision = Convert.ToInt32(field.NewValue);
            }

            foreach (StringField field in workItemChangedEvent.ChangedFields.StringFields)
            {
                // If the field matches any of the ones indicated in the config file as containing "completed 
                // work" data, then record the completed amount change to the database
                foreach (TimeAmount timeAmount in timesheetSettings.TimeAmounts)
                {
                    if (timeAmount.CompletedHoursFieldName != field.ReferenceName)
                        continue;

                    workAmountChange = Convert.ToDouble(field.NewValue) - Convert.ToDouble((field.OldValue == "" ? "0" : field.OldValue));

                    if (workAmountChange != 0)
                    {
                        SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["TimesheetDatabase"].ConnectionString);
                        SqlCommand command = new SqlCommand("usp_UPD_TimeOnWorkItem", connection);

                        connection.Open();
                        command.CommandType = CommandType.StoredProcedure;
                        command.Parameters.Add(new SqlParameter("@workItemId", workItemId));
                        command.Parameters.Add(new SqlParameter("@sid", workItemChangedEvent.ChangerSid));
                        command.Parameters.Add(new SqlParameter("@workAmountChange", workAmountChange));
                        command.Parameters.Add(new SqlParameter("@fieldName", field.ReferenceName));
                        command.Parameters.Add(new SqlParameter("@revision", revision));

                        command.ExecuteNonQuery();
                        connection.Close();
                    }
                }
            }
        }
    }
}
